﻿using System;
using System.Runtime.CompilerServices;
using System.Threading;

namespace MathService.Service
{
    public class ThreadWatcher : IDisposable
    {
        public event EventHandler<EventArgs<Thread>> ThreadEvent;

        protected virtual void OnThreadEvent(EventArgs<Thread> Args)
        {
            ThreadEvent.FastStart(this, Args);
        }
        private void OnThreadEvent() { OnThreadEvent(new EventArgs<Thread>(ThreadToWatch)); }

        private Timer f_WatchTimer;

        public int Timeout { get; private set; }

        public Thread ThreadToWatch { get; private set; }

        public ThreadWatcher(int Timeout) : this(Thread.CurrentThread, Timeout) { }

        public ThreadWatcher(Thread ThreadToWatch, int Timeout)
        {
            this.Timeout = Timeout;
            this.ThreadToWatch = ThreadToWatch;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Start()
        {
            if(f_WatchTimer != null) Stop();
            f_WatchTimer = new Timer(OnTimer, null, Timeout, System.Threading.Timeout.Infinite);
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        public void Stop()
        {
            if(f_WatchTimer == null) return;
            f_WatchTimer.Dispose();
            f_WatchTimer = null;
        }

        [MethodImpl(MethodImplOptions.Synchronized)]
        private void OnTimer(object State)
        {
            if(f_WatchTimer == null) return;
            OnThreadEvent();
            Stop();
        }

        public void Dispose() { Stop(); }
    }
}
